﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Animation;
using System.Windows;

namespace WrWpf.Windows.Media.Animation
{
    public class GridLengthAnimation : AnimationTimeline
    {
        #region Override functions
        /// <summary>
        /// When overridden in a derived class, gets the <see cref="T:System.Type"/> of property that can be animated.
        /// </summary>
        /// <value></value>
        /// <returns>The type of property that can be animated by this animation.</returns>
        public override Type TargetPropertyType
        {
            get { return typeof(GridLength); }
        }

        /// <summary>
        /// When implemented in a derived class, creates a new instance of the <see cref="T:System.Windows.Freezable"/> derived class.
        /// </summary>
        /// <returns>The new instance.</returns>
        protected override System.Windows.Freezable CreateInstanceCore()
        {
            return new GridLengthAnimation();
        }
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes the <see cref="GridLengthAnimation"/> class.
        /// </summary>
        static GridLengthAnimation()
        {
            FromProperty = DependencyProperty.Register("From", typeof(GridLength),
                typeof(GridLengthAnimation));

            ToProperty = DependencyProperty.Register("To", typeof(GridLength),
                typeof(GridLengthAnimation));
        }
        #endregion

        #region Dependency Properties
        /// <summary>
        /// 
        /// </summary>
        public static readonly DependencyProperty FromProperty;
        /// <summary>
        /// Gets or sets from.
        /// </summary>
        /// <value>From.</value>
        public GridLength From
        {
            get
            {
                return (GridLength)GetValue(GridLengthAnimation.FromProperty);
            }
            set
            {
                SetValue(GridLengthAnimation.FromProperty, value);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public static readonly DependencyProperty ToProperty;
        /// <summary>
        /// Gets or sets to.
        /// </summary>
        /// <value>To.</value>
        public GridLength To
        {
            get
            {
                return (GridLength)GetValue(GridLengthAnimation.ToProperty);
            }
            set
            {
                SetValue(GridLengthAnimation.ToProperty, value);
            }
        }
        #endregion

        #region public functions
        /// <summary>
        /// Gets the current value of the animation.
        /// </summary>
        /// <param name="defaultOriginValue">The origin value provided to the animation if the animation does not have its own start value. If this animation is the first in a composition chain it will be the base value of the property being animated; otherwise it will be the value returned by the previous animation in the chain.</param>
        /// <param name="defaultDestinationValue">The destination value provided to the animation if the animation does not have its own destination value.</param>
        /// <param name="animationClock">The <see cref="T:System.Windows.Media.Animation.AnimationClock"/> which can generate the <see cref="P:System.Windows.Media.Animation.Clock.CurrentTime"/> or <see cref="P:System.Windows.Media.Animation.Clock.CurrentProgress"/> value to be used by the animation to generate its output value.</param>
        /// <returns></returns>
        public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
        {
            double fromVal = ((GridLength)GetValue(GridLengthAnimation.FromProperty)).Value;
            double toVal = ((GridLength)GetValue(GridLengthAnimation.ToProperty)).Value;

            if (fromVal > toVal)
            {
                return new GridLength((1 - animationClock.CurrentProgress.Value) *
                    (fromVal - toVal) + toVal, GridUnitType.Star);
            }
            else
            {
                return new GridLength(animationClock.CurrentProgress.Value *
                    (toVal - fromVal) + fromVal, GridUnitType.Star);
            }
        }
        #endregion
    }
}
